package request

import (
	"fmt"
	"gitee.com/stevenchin/gin_study/response"
	"github.com/gin-gonic/gin"
	"net/http"
)

// 定义接收数据的结构体
type Login struct {
	// binding:"required"修饰的字段为必填字段，若接收为空值则会报错
	// TIPS：属于结构体验证部分，结构体验证的具体代码见 paramcalibration7 包下代码
	User     string `json:"user" form:"username" uri:"user" xml:"user" binding:"required"`
	Password string `json:"password" form:"password" uri:"password" xml:"password"`
}

// JsonTest Json 数据解析和绑定
func JsonTest(ctx *gin.Context) {
	login := Login{}
	i := &login
	// ShouldBindJSON 和 BindJSON 都是 gin 框架中用于处理 JSON 数据的方法，但它们在使用方式和功能上有一些区别：
	// BindJSON 方法会将请求体中的 JSON 数据绑定到指定的结构体或变量上。这个方法将尝试将 JSON 数据解析为指定的类型，并将解析后的数据绑定到结构体字段或变量相应的字段上。如果解析失败或绑定失败，BindJSON 将返回错误
	// ShouldBindJSON 方法与 BindJSON 类似，也是将请求体中的 JSON 数据绑定到指定的结构体或变量上。不同之处在于，如果无法将请求体中的 JSON 数据绑定到指定的结构体或变量上时，ShouldBindJSON 不会返回错误，而是简单地不进行绑定
	if err := ctx.ShouldBindJSON(i); err != nil {
		response.Error(response.Data{
			Ctx:     ctx,
			Code:    http.StatusBadRequest,
			Message: err.Error(),
		})
		return
	}
	returnInfo(i, ctx)
}

// FormTest 表单数据解析和绑定
func FormTest(ctx *gin.Context) {
	login := Login{}
	i := &login
	if err := ctx.Bind(i); err != nil {
		response.Error(response.Data{
			Ctx:     ctx,
			Message: err.Error(),
			Code:    http.StatusBadRequest,
		})
		return
	}
	returnInfo(i, ctx)
}

// XmlTest xml 数据解析和绑定
func XmlTest(ctx *gin.Context) {
	login := Login{}
	i := &login
	if err := ctx.BindXML(i); err != nil {
		response.Error(response.Data{
			Ctx:     ctx,
			Message: err.Error(),
			Code:    http.StatusBadRequest,
		})
		return
	}
	returnInfo(i, ctx)
}

// UriTest URI 数据解析和绑定
func UriTest(ctx *gin.Context) {
	login := new(Login)
	if err := ctx.ShouldBindUri(login); err != nil {
		response.Error(response.Data{
			Ctx:     ctx,
			Message: err.Error(),
			Code:    http.StatusBadRequest,
		})
		return
	}
	returnInfo(login, ctx)
}

// JsonAndUri Uri + Json 数据解析和绑定
func JsonAndUri(ctx *gin.Context) {
	name := ctx.Param("user")
	password := ctx.Param("password")
	fmt.Printf("user is %s，password is %s \n", name, password)
	login := new(Login)
	if err := ctx.ShouldBindJSON(login); err != nil {
		response.Error(response.Data{
			Ctx:     ctx,
			Code:    http.StatusBadRequest,
			Message: err.Error(),
		})
		return
	}
	returnInfo(login, ctx)
}

func returnInfo(login *Login, ctx *gin.Context) {
	// 判断用户名密码是否正确
	if login.User != "root" || login.Password != "admin" {
		response.Error(response.Data{Ctx: ctx, Code: http.StatusNotModified, Message: "权限认证失败"})
		return
	}
	// 验证成功返回登录信息
	response.Success(response.Data{
		Ctx:  ctx,
		Data: login,
	})
}
